package com.pn.controller;

import com.google.code.kaptcha.Producer;
import com.pn.entity.LoginUser;
import com.pn.entity.Result;
import com.pn.model.AuthInfo;
import com.pn.model.UserInfo;
import com.pn.service.AuthInfoService;
import com.pn.service.UserInfoService;
import com.pn.utils.CurrentUser;
import com.pn.utils.DigestUtil;
import com.pn.utils.TokenUtils;
import com.pn.utils.WarehouseConstants;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.TimeUnit;

@RestController
public class LoginController {

    //注入对象-生成验证码图片
    @Resource(name = "captchaProducer")
    private Producer producer;

    //注入redis模版
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private UserInfoService userInfoService;

    @Autowired
    private TokenUtils tokenUtils;

    @Autowired
    private AuthInfoService authInfoService;

    /**
     * 生成验证码
     * @param response
     */
    @RequestMapping("/captcha/captchaImage")
    public void captchaImage(HttpServletResponse response){

        ServletOutputStream out = null;
        try {
            //生成验证码图片文件
            String text = producer.createText();
            //使用验证码文本生成验证码图片--在内存中
            BufferedImage image = producer.createImage(text);
            //验证码文本作为键保存到redis---设置键的过期时间为30分钟
            stringRedisTemplate.opsForValue().set(text,"",60*30, TimeUnit.SECONDS);
            /*
             * 将验证码图片响应给前端
             */
            //设置响应正文image/jpeg
            response.setContentType("image/jpeg");
            //将验证码图片响应给前端
            out = response.getOutputStream();
            ImageIO.write(image,"jpg",out);//使用响应对象的字节输出流写入验证码图片，写个前端
            //刷新
            out.flush();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }finally {
            //关闭字节输出流
            if (out!= null){
                try {
                    out.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }

    /**
     * 登录按钮接口
     * @RequestBody LoginUser loginUser--表示接收并封装前端传递的登录的用户信息的json数据
     * 返回值Result ---表示向前端想用结果result对象转的json串，包含响应状态码 成功失败响应 响应信息 响应数据；
     * @param loginUser
     * @return
     */
    @RequestMapping("/login")
    public Result login(@RequestBody LoginUser loginUser){

        String code = loginUser.getVerificationCode();
        if(!stringRedisTemplate.hasKey(code)){
            return Result.err(Result.CODE_ERR_BUSINESS,"验证码错误！");
        }

        UserInfo userInfo = userInfoService.queryUserInfoByCode(loginUser.getUserCode());
        if(userInfo != null){
            if(userInfo.getUserState().equals(WarehouseConstants.USER_STATE_PASS)){//用户已审核
                String userPwd = loginUser.getUserPwd();
                //进行md5加密
                userPwd = DigestUtil.hmacSign(userPwd);
                if(userPwd.equals(userInfo.getUserPwd())){//密码合法
                    //生成jwt token并存储到redis
                    CurrentUser currentUser =
                            new CurrentUser(userInfo.getUserId(),userInfo.getUserCode(),userInfo.getUserName());
                    String token = tokenUtils.loginSign(currentUser,userPwd);
                    //向客户响应jwt token
                    return Result.ok("登录成功！",token);
                }else{
                    return Result.err(Result.CODE_ERR_BUSINESS,"密码错误");
                }
            }else{
                return Result.err(Result.CODE_ERR_BUSINESS,"用户未审核");
            }

        }else {
            return Result.err(Result.CODE_ERR_BUSINESS,"账号不存在");
        }
    }


    /**
     * 获取当前登录的用户信息的url
     *@RequestHeader(WarehouseConstants.HEADER_TOKEN_NAME) String token
     * 表示将请求头Token的值（前端归还的token赋值给请求处理方法入参变量token）
     * @param token
     * @return
     */
    @RequestMapping("/curr-user")
    public Result currentUser(@RequestHeader(WarehouseConstants.HEADER_TOKEN_NAME) String token){

        //解token拿到封装了当前用户登录信息的CurrentUser对象
        CurrentUser currentUser = tokenUtils.getCurrentUser(token);
        //响应
        return Result.ok(currentUser);
    }

    /**
     * 加载用户权限菜单树的url接口
     * @param token
     * @return
     */
    @RequestMapping("/user/auth-list")
    private Result loadAuthTree(@RequestHeader(WarehouseConstants.HEADER_TOKEN_NAME) String token){
        //拿到当前登录用户的id
        CurrentUser currentUser = tokenUtils.getCurrentUser(token);
        int userId = currentUser.getUserId();

        //执行业务
        List<AuthInfo> authTreeList = authInfoService.queryAuthTreeById(userId);

        return Result.ok(authTreeList);
    }

    @RequestMapping("/logout")
    public Result logout(@RequestHeader(WarehouseConstants.HEADER_TOKEN_NAME) String token){
        stringRedisTemplate.delete(token);
        //响应
        return  Result.ok("退出系统！");
    }
}
